{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "id": "K4kObERVUvo1",
    "colab_type": "code",
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 125.0
    },
    "outputId": "203a5ac0-0006-4616-ff0b-439f9917b3bf"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch: 001000 cost = 0.001538\n",
      "Epoch: 002000 cost = 0.000269\n",
      "Epoch: 003000 cost = 0.000093\n",
      "Epoch: 004000 cost = 0.000040\n",
      "Epoch: 005000 cost = 0.000020\n",
      "sorry hate you is Bad Mean...\n"
     ]
    }
   ],
   "source": [
    "'''\n",
    "  code by Tae Hwan Jung(Jeff Jung) @graykode\n",
    "  Reference : https://github.com/ioatr/textcnn\n",
    "'''\n",
    "import tensorflow as tf\n",
    "import numpy as np\n",
    "\n",
    "tf.reset_default_graph()\n",
    "\n",
    "# Text-CNN Parameter\n",
    "embedding_size = 2 # n-gram\n",
    "sequence_length = 3\n",
    "num_classes = 2 # 0 or 1\n",
    "filter_sizes = [2,2,2] # n-gram window\n",
    "num_filters = 3\n",
    "\n",
    "# 3 words sentences (=sequence_length is 3)\n",
    "sentences = [\"i love you\",\"he loves me\", \"she likes baseball\", \"i hate you\",\"sorry for that\", \"this is awful\"]\n",
    "labels = [1,1,1,0,0,0] # 1 is good, 0 is not good.\n",
    "\n",
    "word_list = \" \".join(sentences).split()\n",
    "word_list = list(set(word_list))\n",
    "word_dict = {w: i for i, w in enumerate(word_list)}\n",
    "vocab_size = len(word_dict)\n",
    "\n",
    "inputs = []\n",
    "for sen in sentences:\n",
    "    inputs.append(np.asarray([word_dict[n] for n in sen.split()]))\n",
    "\n",
    "outputs = []\n",
    "for out in labels:\n",
    "    outputs.append(np.eye(num_classes)[out]) # ONE-HOT : To using Tensor Softmax Loss function\n",
    "\n",
    "# Model\n",
    "X = tf.placeholder(tf.int32, [None, sequence_length])\n",
    "Y = tf.placeholder(tf.int32, [None, num_classes])\n",
    "\n",
    "W = tf.Variable(tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0))\n",
    "embedded_chars = tf.nn.embedding_lookup(W, X) # [batch_size, sequence_length, embedding_size]\n",
    "embedded_chars = tf.expand_dims(embedded_chars, -1) # add channel(=1) [batch_size, sequence_length, embedding_size, 1]\n",
    "\n",
    "pooled_outputs = []\n",
    "for i, filter_size in enumerate(filter_sizes):\n",
    "    filter_shape = [filter_size, embedding_size, 1, num_filters]\n",
    "    W = tf.Variable(tf.truncated_normal(filter_shape, stddev=0.1))\n",
    "    b = tf.Variable(tf.constant(0.1, shape=[num_filters]))\n",
    "\n",
    "    conv = tf.nn.conv2d(embedded_chars, # [batch_size, sequence_length, embedding_size, 1]\n",
    "                        W,              # [filter_size(n-gram window), embedding_size, 1, num_filters(=3)]\n",
    "                        strides=[1, 1, 1, 1],\n",
    "                        padding='VALID')\n",
    "    h = tf.nn.relu(tf.nn.bias_add(conv, b))\n",
    "    pooled = tf.nn.max_pool(h,\n",
    "                            ksize=[1, sequence_length - filter_size + 1, 1, 1], # [batch_size, filter_height, filter_width, channel]\n",
    "                            strides=[1, 1, 1, 1],\n",
    "                            padding='VALID')\n",
    "    pooled_outputs.append(pooled) # dim of pooled : [batch_size(=6), output_height(=1), output_width(=1), channel(=1)]\n",
    "\n",
    "num_filters_total = num_filters * len(filter_sizes)\n",
    "h_pool = tf.concat(pooled_outputs, num_filters) # h_pool : [batch_size(=6), output_height(=1), output_width(=1), channel(=1) * 3]\n",
    "h_pool_flat = tf.reshape(h_pool, [-1, num_filters_total]) # [batch_size, ]\n",
    "\n",
    "# Model-Training\n",
    "Weight = tf.get_variable('W', shape=[num_filters_total, num_classes], \n",
    "                    initializer=tf.contrib.layers.xavier_initializer())\n",
    "Bias = tf.Variable(tf.constant(0.1, shape=[num_classes]))\n",
    "model = tf.nn.xw_plus_b(h_pool_flat, Weight, Bias)  \n",
    "cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=model, labels=Y))\n",
    "optimizer = tf.train.AdamOptimizer(0.001).minimize(cost)\n",
    "\n",
    "# Model-Predict\n",
    "hypothesis = tf.nn.softmax(model)\n",
    "predictions = tf.argmax(hypothesis, 1)\n",
    "# Training\n",
    "init = tf.global_variables_initializer()\n",
    "sess = tf.Session()\n",
    "sess.run(init)\n",
    "\n",
    "for epoch in range(5000):\n",
    "    _, loss = sess.run([optimizer, cost], feed_dict={X: inputs, Y: outputs})\n",
    "    if (epoch + 1)%1000 == 0:\n",
    "        print('Epoch:', '%06d' % (epoch + 1), 'cost =', '{:.6f}'.format(loss))\n",
    "\n",
    "# Test\n",
    "test_text = 'sorry hate you'\n",
    "tests = []\n",
    "tests.append(np.asarray([word_dict[n] for n in test_text.split()]))\n",
    "\n",
    "predict = sess.run([predictions], feed_dict={X: tests})\n",
    "result = predict[0][0]\n",
    "if result == 0:\n",
    "    print(test_text,\"is Bad Mean...\")\n",
    "else:\n",
    "    print(test_text,\"is Good Mean!!\")"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "name": "TextCNN-Tensor.ipynb",
   "version": "0.3.2",
   "provenance": [],
   "collapsed_sections": []
  },
  "kernelspec": {
   "name": "python3",
   "display_name": "Python 3"
  },
  "accelerator": "GPU"
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
